package com.rongji.dfish.base.util;

/**
 * 执行数学任务的工具类
 */
public class MathUtil {

    /**
     * 最大数
     * @param i int
     * @return int
     */
    public static int max(int... i) {
        int result = Integer.MIN_VALUE;
        for (int inte : i) {
            if (result < inte) {
                result = inte;
            }
        }
        return result;
    }
    /**
     * 最大数
     * @param l long
     * @return long
     */
    public static long max(long... l) {
        long result = Long.MIN_VALUE;
        for (long num : l) {
            if (result < num) {
                result = num;
            }
        }
        return result;
    }
    /**
     * 最大数
     * @param d double
     * @return double
     */
    public static double max(double... d) {
        double result = Double.MIN_VALUE;
        for (double num : d) {
            if (result < num) {
                result = num;
            }
        }
        return result;
    }
    /**
     * 最大数
     * @param f float
     * @return float
     */
    public static float max(float... f) {
        float result = Float.MIN_VALUE;
        for (float num : f) {
            if (result < num) {
                result = num;
            }
        }
        return result;
    }

    /**
     * 最小数
     * @param i int
     * @return int
     */
    public static int min(int... i) {
        int result = Integer.MAX_VALUE;
        for (int num : i) {
            if (result > num) {
                result = num;
            }
        }
        return result;
    }

    /**
     * 最小数
     * @param l long
     * @return long
     */
    public static long min(long... l) {
        long result = Long.MAX_VALUE;
        for (long num : l) {
            if (result > num) {
                result = num;
            }
        }
        return result;
    }
    /**
     * 最小数
     * @param d double
     * @return double
     */
    public static double min(double... d) {
        double result = Double.MAX_VALUE;
        for (double num : d) {
            if (result > num) {
                result = num;
            }
        }
        return result;
    }
    /**
     * 最小数
     * @param f float
     * @return float
     */
    public static float min(float... f) {
        float result = Float.MAX_VALUE;
        for (float num : f) {
            if (result > num) {
                result = num;
            }
        }
        return result;
    }

    private static final long MAX_DENOMINATOR = 1000000; // 最大分母限制
    private static final double EPSILON = 1e-8;         // 误差阈值

    /**
     * 将小数转换为分数
     *
     * @param number 输入的小数
     * @return 分数形式的字符串
     */
    public static String doubleToFraction(double number) {
        // 处理特殊值：NaN 和无穷大
        if (Double.isNaN(number) || Double.isInfinite(number)) {
            return String.valueOf(number);
        }

        // 处理零值
        if (number == 0.0) {
            return "0";
        }

        // 记录是否为负数，并转为正数处理
        boolean isNegative = number < 0;
        double num = Math.abs(number);


        // 整数部分
        long integerPart = (long) Math.floor(num);
        double fractional = num - integerPart;

        // 处理纯整数情况
        if (fractional < EPSILON) {
            return isNegative ? ("-" + integerPart) : String.valueOf(integerPart);
        }

        // 使用连分数算法处理小数部分
        long prevNumerator = 1;  // 前前分子
        long prevDenominator = 0; // 前前分母
        long currentNumerator = integerPart; // 前分子
        long currentDenominator = 1; // 前分母

        double x = fractional;
        long bestNumerator = currentNumerator;
        long bestDenominator = currentDenominator;
        double bestError = Math.abs(num - (double) bestNumerator / bestDenominator);

        // 连分数迭代
        while (x > EPSILON) {
            // 计算倒数和小数部分
            double reciprocal = 1.0 / x;
            long a = (long) Math.floor(reciprocal);
            double remainder = reciprocal - a;

            // 计算新分子和分母
            long newNumerator = a * currentNumerator + prevNumerator;
            long newDenominator = a * currentDenominator + prevDenominator;

            // 分母超过限制则停止
            if (newDenominator > MAX_DENOMINATOR) {
                break;
            }

            // 更新前两项
            prevNumerator = currentNumerator;
            prevDenominator = currentDenominator;
            currentNumerator = newNumerator;
            currentDenominator = newDenominator;

            // 计算当前误差
            double currentValue = (double) currentNumerator / currentDenominator;
            double currentError = Math.abs(num - currentValue);

            // 更新最佳结果
            if (currentError < bestError) {
                bestNumerator = currentNumerator;
                bestDenominator = currentDenominator;
                bestError = currentError;
            }

            // 误差足够小则提前退出
            if (currentError < EPSILON) {
                break;
            }

            x = remainder;
        }

        // 约分
        long gcd = gcd(bestNumerator, bestDenominator);
        bestNumerator /= gcd;
        bestDenominator /= gcd;

        // 恢复负号
        if (isNegative) {
            bestNumerator = -bestNumerator;
        }

        // 格式化输出
        if (bestDenominator == 1) {
            return String.valueOf(bestNumerator);
        } else {
            return bestNumerator + "/" + bestDenominator;
        }
    }


    /**
     * 计算最大公约数（GCD）
     *
     * @param a
     * @param b
     * @return
     */
    public static long gcd(long a, long b) {
        a = Math.abs(a);
        b = Math.abs(b);
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }
}
